package net.grandnature.android.morse.player;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class SoundDataUtils {
	private SoundDataUtils(){}
	/**
	 * 16bitPCMのRAWデータを読んで1.0から-1.0の範囲のdoubleに正規化して返す
	 * @param file
	 * @return
	 */
	public static double[] load16BitPCMRawDataFileAsDoubleArray(File file) {
		InputStream in = null;
		if (file.isFile()) {
			long size = file.length();
			try {
				in = new FileInputStream(file);
				return readStreamAsDoubleArray(in, size);
			} catch (Exception e) {
			} finally {
				if (in != null) {
					try {
						in.close();
					} catch (IOException e) {
					}
				}
			}
		}
		throw new RuntimeException("couldn't read:" + file.getName());
	}
	// shortだと誤差が激しいので1.0から-1.0の範囲のdoubleに正規化
	public static double[] readStreamAsDoubleArray(InputStream in, long size) throws IOException {
		int bufferSize = (int)(size / 2);
		double[] result = new double[bufferSize];
		DataInputStream is = new DataInputStream(in);
		for (int i = 0; i < bufferSize; i++) {
			result[i]= is.readShort()/32768.0;
		}
		return result;
	}
	// shortだと誤差が激しいので1.0から-1.0の範囲のdoubleに正規化
	public static double[] convertFromShortArrayToDoubleArray(short[] shortData) {
		int size = shortData.length;
		double[] doubleData = new double[size];
		for (int i = 0; i < size; i++) {
			doubleData[i]= shortData[i]/32768.0;
		}
		return doubleData;
	}
	// doubleだと再生できないのでshortに直して返す
	public static short[] convertFromDoubleArrayToShortArray(double[] doubleData) {
		int size = doubleData.length;
		short[] shortData = new short[size];
		for (int i = 0; i < size; i++) {
			double d = (doubleData[i] + 1.0)/2.0 * 65536.0;
			if(d > 65535.0) {
				d = 65535.0;
			} else if(d < 0.0) {
				d = 0.0;
			}
			shortData[i] = (short)((d + 0.5) - 32768);
		}
		return shortData;
	}
}
